/****************************************************************************
**  FougTools
**  Copyright Fougue (1 Mar. 2011)
**  contact@fougue.pro
**
** This software is a computer program whose purpose is to provide utility
** tools for the C++ language and the Qt toolkit.
**
** This software is governed by the CeCILL-C license under French law and
** abiding by the rules of distribution of free software.  You can  use,
** modify and/ or redistribute the software under the terms of the CeCILL-C
** license as circulated by CEA, CNRS and INRIA at the following URL
** "http://www.cecill.info".
****************************************************************************/

#pragma once

#include <cstddef>

namespace cpp {

/*! Gives the address in \p pointer as a numeric(scalar) value
 *  \ingroup cpptools
 */
template <typename T>
std::size_t scalarAddress(const T* pointer)
{
    return reinterpret_cast<std::size_t>(pointer);
}

/*! Frees memory in \p pointer, and sets pointer to NULL
 *  \ingroup cpptools
 */
template<typename T>
void checkedReset(T*& pointer)
{
    if (pointer != NULL) {
        delete pointer;
        pointer = NULL;
    }
}

/*! Assigns \p value at memory in \p pointer if valid (ie. non-NULL)
 *  \ingroup cpptools
 */
template<typename T>
void checkedAssign(T* pointer, T value)
{
    if (pointer != NULL)
        *pointer = value;
}

/*! Assigns \p value to object member attribute \p attrMember if valid (ie. non-NULL)
 *  \ingroup cpptools
 */
template<typename CALL_VALUE_TYPE, typename VALUE_TYPE, typename CLASS>
void checkedAssign(VALUE_TYPE CLASS::*attrMember, CLASS* object, CALL_VALUE_TYPE value)
{
    if (object != NULL && attrMember != NULL)
        object->*attrMember = value;
}

/*! Returns a heap-allocated instance of T, created with the default constructor
 *
 *  \tparam T Must be default constructible
 *          (see http://www.sgi.com/tech/stl/DefaultConstructible.html)
 *  \ingroup cpptools
 */
template<typename T>
T* newObject()
{
    return new T;
}

template<typename T, typename ARG>
T* newObject(ARG arg)
{
    return new T(arg);
}

} // namespace cpp
